﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace SharpOSCAR.Base
{
    /// <summary>
    /// Represents an array of TLVs.
    /// </summary>
    public class TlvLBlock : ProtocolData, ITlvContainer
    {
        private LinkedList<Tlv> _TLVs;

        /// <summary>
        /// Default constructor
        /// </summary>
        public TlvLBlock()
        {
            _TLVs = new LinkedList<Tlv>();
        }

        /// <summary>
        /// Adds a new TLV to the TlvLBlock
        /// </summary>
        /// <param name="value">TLV to add</param>
        public void AddTlv(Tlv value)
        {
            _TLVs.AddLast(value);
        }

        /// <summary>
        /// Removes a TLV from the TlvLBlock
        /// </summary>
        /// <param name="value">TLV to remove</param>
        public void RemoveTlv(Tlv value)
        {
            _TLVs.Remove(value);
        }

        /// <summary>
        /// Gets the number of TLVs in the container
        /// </summary>
        public int Count
        {
            get
            {
                return _TLVs.Count;
            }
        }

        /// <summary>
        /// Gets the length of the TlvLBlock -- processor intensive, use sparingly
        /// </summary>
        public ushort Length
        {
            get
            {
                ushort val = 0;
                foreach (Tlv value in _TLVs)
                    val += Convert.ToUInt16(value.Length + 4);
                return val;
            }
        }

        /// <summary>
        /// Converts the TlvLBlock into a byte array representing the block and all TLVs contained inside of it
        /// </summary>
        /// <returns>Returns a byte array representing the TlvLBlock</returns>
        public override byte[] ToByteArray()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // Write the length of the TlvLBlock to the array
                byte[] lenBytes = BitConverter.GetBytes(Length);
                ms.Write(lenBytes, 0, lenBytes.Length);

                // Write each TLV to the array 
                foreach (Tlv value in _TLVs)
                {
                    byte[] tlvValue = value.ToByteArray();
                    ms.Write(tlvValue, 0, tlvValue.Length);
                }

                // Return the generated byte array
                return ms.ToArray();
            }
        }
    }
}
